package com.kzn.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.kzn.entity.*;
import com.kzn.mapper.*;
import com.kzn.service.IDetailedTaskService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.kzn.util.Dom4jUtil;
import com.kzn.util.ResponseVo;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import sun.misc.BASE64Encoder;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author sorclown
 * @since 2022-02-05
 */
@Service
public class DetailedTaskServiceImpl extends ServiceImpl<DetailedTaskMapper, DetailedTask> implements IDetailedTaskService {

    private DetailedTaskMapper detailedTaskMapper;
    private RewardPointsMapper rewardPointsMapper;
    private CrowdMapper crowdMapper;


    public DetailedTaskServiceImpl() {
    }

    @Autowired
    public DetailedTaskServiceImpl(DetailedTaskMapper detailedTaskMapper,
                                   RewardPointsMapper rewardPointsMapper,
                                   CrowdMapper crowdMapper) {
        this.detailedTaskMapper = detailedTaskMapper;
        this.rewardPointsMapper = rewardPointsMapper;
        this.crowdMapper = crowdMapper;
    }


    @Override
    public boolean uploadResultByTask(List<Rect> rects, Integer taskId) {

        DetailedTask detailedTask = detailedTaskMapper.selectById(taskId);
        String resourcePath = GlobalVar.UPLOAD_PATH + "/" + detailedTask.getProjectName() + "/image/" + detailedTask.getSourceFilePath();
        int imageWidth = 0;
        int imageHeight = 0;
        File imageFile = new File(resourcePath);
        try {
            BufferedImage image = ImageIO.read(imageFile);
            imageWidth = image.getWidth();
            imageHeight = image.getHeight();
        } catch (IOException e) {
            e.printStackTrace();
        }
        String resultPath = GlobalVar.UPLOAD_PATH + "/" + detailedTask.getProjectName() + "/result/" + detailedTask.getSourceFilePath().split("\\.")[0];

        //本地保存的格式
        String suffix = ".txt";
        //result.path 应该为 upload_path + "/" + projectName + "/result/" + taskResourceFileName(无后缀) + 后缀
        File result = new File(resultPath + suffix);

        //resultFolder.path 应该为 upload_path + "/" + projectName + "/result/"
        File resultFolder = new File(result.getParent());
        if (!resultFolder.exists()) {
            resultFolder.mkdirs();
        }

        //将结果保存为csv格式
        saveAsCSV(rects, detailedTask, imageWidth, imageHeight);
        //将结果保存为VOC格式
        Dom4jUtil.parseRectToVOC(rects, detailedTask, imageWidth, imageHeight);
        //将结果保存为YOLO格式
        List<String> tags = Arrays.asList(detailedTask.getTarget().trim().split(","));
        try (BufferedWriter bw = new BufferedWriter(new FileWriter(result.getPath()));) {

//            bw.append(imageWidth + " " + imageHeight + "\n");
            for (int i = 0; i < rects.size(); i++) {
                bw.append(String.valueOf(tags.indexOf(rects.get(i).getName())));
                bw.append(rects.get(i).getYOLO() + "\n");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        return true;
    }

    /**
     * 将数据存到csv文件中
     *
     * @param rects
     * @param detailedTask
     * @param imageWidth
     * @param imageHeight
     * @return
     */
    public static boolean saveAsCSV(List<Rect> rects, DetailedTask detailedTask, Integer imageWidth, Integer imageHeight) {
        String resultPath = GlobalVar.UPLOAD_PATH + "/" + detailedTask.getProjectName() + "/result_csv.csv";
        try (BufferedWriter bw = new BufferedWriter(new FileWriter(resultPath,true))) {

            for (Rect rect : rects) {
                bw.append(rect.getName()).append(",")
                        .append(String.valueOf((int) (rect.getX() * imageWidth))).append(",")
                        .append(String.valueOf((int) (rect.getY() * imageHeight))).append(",")
                        .append(String.valueOf((int) ((rect.getEx() - rect.getX()) * imageWidth))).append(",")
                        .append(String.valueOf((int) ((rect.getEy() - rect.getY()) * imageHeight))).append(",")
                        .append("./" + detailedTask.getSourceFilePath()).append(",")
                        .append(imageWidth.toString()).append(",")
                        .append(imageHeight.toString()).append("\n");
            }
            return true;
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }

    }


    @Override
    public boolean submit(Integer taskId, Integer crowdId) {
        QueryWrapper<DetailedTask> detailedTaskQueryWrapper = new QueryWrapper<>();
        detailedTaskQueryWrapper.eq("id", taskId);
        detailedTaskQueryWrapper.eq("status", 0);
        DetailedTask detailedTask = detailedTaskMapper.selectOne(detailedTaskQueryWrapper);
        if (null == detailedTask) {
            return false;
        }
        Integer awardPoint = detailedTask.getAwardPoint();
        if (null == crowdMapper.selectById(crowdId)) {
            return false;
        }


        QueryWrapper<RewardPoints> rewardPointsQueryWrapper = new QueryWrapper<>();
        rewardPointsQueryWrapper.eq("crowdId", crowdId);

        if (rewardPointsMapper.exists(rewardPointsQueryWrapper)) {
            //如果是表中已经有了该标注人员
            //从表中获取 rewardPoints 对象
            RewardPoints rewardPoints = rewardPointsMapper.selectOne(rewardPointsQueryWrapper);
            //增加对应点数
            Integer curPoint = rewardPoints.getPoint() + awardPoint;
            rewardPoints.setPoint(curPoint);
            rewardPointsMapper.updateById(rewardPoints);
        } else {
            //如果该标注人员是第一次提交子任务
            //创建 rewardPoints 对象
            RewardPoints rewardPoints = new RewardPoints();
            rewardPoints.setCrowdId(crowdId);
            //保存对应点数
            rewardPoints.setPoint(awardPoint);
            rewardPointsMapper.insert(rewardPoints);
        }

        //将子任务状态改为已完成
        detailedTask.setStatus(1);
        detailedTaskMapper.updateById(detailedTask);
        return true;
    }

    @Override
    public ResponseVo<String> getPictureByTaskId(Integer taskId) {
        DetailedTask detailedTask = detailedTaskMapper.selectById(taskId);
        String resourcePath = GlobalVar.UPLOAD_PATH + "/" + detailedTask.getProjectName() + "/image/" + detailedTask.getSourceFilePath();
        String data;

        try {
            FileInputStream fileInputStream = new FileInputStream(resourcePath);
            ByteArrayOutputStream bos = new ByteArrayOutputStream();

            byte[] b = new byte[1024];
            int len = -1;
            while ((len = fileInputStream.read(b)) != -1) {
                bos.write(b, 0, len);
            }
            byte[] fileByte = bos.toByteArray();

            //进行base64编码
            BASE64Encoder encoder = new BASE64Encoder();
            data = encoder.encode(fileByte);

            return ResponseVo.success(data);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }


}
